'use strict';


// function package() {
//   return 'Hello from package';
// }
const fs = require('fs-extra') // 生成文件或者文件夹
const pkgDir = require('pkg-dir').sync
const npminstall = require('npminstall')
const path = require('path')
const { isObject } = require('@renwang-0103/utils')
const formatPath = require('@renwang-0103/format-path')
const pathExists = require('path-exists').sync
const { getDefaultRegistry, getLatestVesion, getNpmSemverVersions } = require('@renwang-0103/get-npm-info')

class Package {
  constructor(options) {
    if (!options || !isObject(options)) {
      return;
    }
    this.targetPath = options.targetPath // 依赖的路径
    // 远程package存在本地，需要一个存储路径, 缓存路径
    this.storePath = options.storePath
    // package的name
    this.packageName = options.packageName
    // package的版本号
    this.packageVersion = options.packageVersion

    // package的缓存目录前缀
    this.npmCachePathPrefix = this.packageName.replace('/', '+')
  }


  // 查路径的时候，需要具体到包的版本号，
  async prepare() {

    // 生成缓存目录
    if (this.storePath && !pathExists(this.storePath)) {
      // storepath值存在，但是这个路径没有   需要创建
      // mkdirpSync 根据这个地址，创建每一级路径
      fs.mkdirpSync(this.storePath)
    }

    if (this.packageVersion === 'latest') {
      this.packageVersion = await getLatestVesion(this.packageName)
    }
    // console.log(this.packageVersion, '最新的版本');
  }

  /**
   * 拼缓存路径
   */
  get cacheFilePath() {
    return path.resolve(this.storePath, `.store/${this.npmCachePathPrefix}@${this.packageVersion}/node_modules/${this.packageName}`)
  }


  /**
   * 
   * @returns 生成指定版本的路径
   */
  getLatestFilePath(packageVersion) {
    return path.resolve(this.storePath, `.store/${this.npmCachePathPrefix}@${packageVersion}/node_modules/${this.packageName}`)
  }

  // 判断包是否存在
  async isExit() {

    if (this.storePath) {
      console.log('真的');
      // 当前是缓存模式
      await this.prepare()
      console.log(this.cacheFilePath, 'cacheFilePath');
      return pathExists(this.cacheFilePath)
    } else {
      console.log('假的');
      return pathExists(this.targetPath)
    }
  }

  // 安装package
  async install() {
    await this.prepare()
    console.log(this.packageVersion, 'packageVersion');
    console.log(this.targetPath, 'targetPath');
    console.log(this.storePath, 'storePath');
    console.log(getDefaultRegistry(true), 'getDefaultRegistry(true)');
    return npminstall({
      root: this.targetPath,
      storeDir: this.storePath,
      registry: getDefaultRegistry(true),
      pkgs: [
        { name: this.packageName, version: this.packageVersion }
      ]
    })
  }

  // 更新package
  async update() {
    await this.prepare()
    console.log('我开始更新了');
    // 当前的包已经安装好了，再判断，包是不是最新的，如果是，就啥都不做，
    // 如果不是最新的，需要更新

    // 获取最新的版本号，再用最新的版本号拼接的路径去查这个路径是否存在，如果不存在，就需要更新
    const lastestPackageVersion = await getLatestVesion(this.packageName)
    console.log(lastestPackageVersion, 'lastestPackageVersion');
    // 生成最新路径
    const latestPath = this.getLatestFilePath(lastestPackageVersion)
    console.log(latestPath, 'latestPath---latestPath', !pathExists(latestPath));
    // 判断路径存在不
    if (!pathExists(latestPath)) {
      await npminstall({
        root: this.targetPath,
        storeDir: this.storePath,
        registry: getDefaultRegistry(true),
        pkgs: [
          { name: this.packageName, version: lastestPackageVersion }
        ]
      })
      // 安装最新包后，更新 this.packageVersion
      this.packageVersion = lastestPackageVersion
    }

  }

  // 获取入口文件的路径
  getRootFilePath() {

    // 读取找到的package.json,  通过require引入就可以

    // 找package.json里面的main字段。  或者是bin字段

    // 路径兼容
    const packageName = this.packageName
    const storePath = this.storePath

    function getRootFile(pathChange) {
      // 获取模块的package.json的目录    pkg-dir库可以实现
      
      let dir = null;
      /**
       * 这里判断缓存路径，是区分 手动输入和自动填充的时候，路径会有不一样的情况
       */
      if (storePath) {
        const pp = path.resolve(pathChange, 'node_modules', packageName)
        dir = pkgDir(pp)
      } else {
        dir = pkgDir(pathChange)
      }
      // const dir = pkgDir(pp)
      // pkgDir 这个库的目的是判断当前目录中是否含有  package.json文件
      // console.log(pp, '呵呵', dir);
      if (dir) {
        // 如果读取的路径存在，就读package.json

        // path.resolve用链接路径的意思
        const pkgjson = require(path.resolve(dir, 'package.json'))
        // console.log(this.packageName, this.targetPath, pkgjson, '急急急', pkgjson.main, dir, path.resolve(dir, 'package.json'));
        if (pkgjson && pkgjson.main) {
          // 兼容处理
          return formatPath(path.resolve(dir, pkgjson.main))
        }
        return null
      }
      return dir
    }

    if (this.storePath) {
      // 存在缓存的时候，就是手动命令中没有输入路径的时候
      return getRootFile(this.cacheFilePath)
    } else {
      // 手动命令中输入路径的时候
      return getRootFile(this.targetPath)
    }


  }


}
module.exports = Package;
